package cn.accjiyun.pki.controller.certificate;

import cn.accjiyun.pki.common.constants.CommonConstants;
import cn.accjiyun.pki.common.controller.BaseController;
import cn.accjiyun.pki.common.utils.DateUtils;
import cn.accjiyun.pki.common.utils.SingletonLoginUtils;
import cn.accjiyun.pki.common.utils.WebUtils;
import cn.accjiyun.pki.entity.SystemUser;
import cn.accjiyun.pki.service.SystemUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;

/**
 * Created by jiyun on 2017/5/24.
 */
@Controller
@RequestMapping("/admin/cert")
public class CertificateController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(CertificateController.class);
    private static String cerPage = getViewPath("/admin/certificate/certificate");

    @Autowired
    private SystemUserService systemUserService;

    @RequestMapping("/generateCert")
    @ResponseBody
    public String generateCert(HttpServletRequest request, HttpServletResponse response) {
        SystemUser systemUser = SingletonLoginUtils.getLoginSystemUser(request);
        if (WebUtils.isValidateRealString(systemUser.getPukUrl())) {
            return getReturnJson(400, "该用户已经申请过证书！", null);
        }
        int userId = systemUser.getId();
        String password = request.getParameter("password");
        if (password == null) {
            return getReturnJson(400, "密码不能为空！", null);
        }
//        String realPath = request.getServletContext().getRealPath("WEB-INF/certificate/")
//                + DateUtils.formatDate(new Date(), "yyyyMMdd");

        String realPath = "D:/pki/"
                + DateUtils.formatDate(new Date(), "yyyyMMdd");

        String pfxUrl = CommonConstants.CA_DOMAIN + "/generateCert/" + userId + "?password=" + password;
        String pfxPath = requestDownload(pfxUrl, realPath, ".pfx");
        new File(pfxPath).delete();

        String cerUrl = CommonConstants.CA_DOMAIN + "/getPukCert/" + userId;
        String cerPath = requestDownload(cerUrl, realPath, ".cer");
        if (cerPath == null) {
            return getReturnJson(404, "申请证书失败！", null);
        }
        systemUser.setPukUrl(cerPath);
        systemUserService.updateSystemUser(systemUser);

//        downloadCer(new File(pfxPath), response);
//        return null;
        return getReturnJson(200, "申请成功！", null);
    }

    @RequestMapping("/getPukCert")
    @ResponseBody
    public String getPukCert(HttpServletRequest request, HttpServletResponse response) {
        SystemUser systemUser = SingletonLoginUtils.getLoginSystemUser(request);
        if (!WebUtils.isValidateRealString(systemUser.getPukUrl())) {
            return getReturnJson( 400, "该用户还没有申请证书！", null);
        }
        File cerFile = new File(systemUser.getPukUrl());
        responseDownload(cerFile, response);
        return null;
    }

    @RequestMapping("/getPfxCert")
    public String getPfxCert(HttpServletRequest request, HttpServletResponse response) {
        SystemUser systemUser = SingletonLoginUtils.getLoginSystemUser(request);
        String password = request.getParameter("password");
        if (!WebUtils.isValidateRealString(systemUser.getPukUrl())) {
            return getReturnJson( 400, "该用户还没有申请证书！", null);
        }
        String pfxUrl = CommonConstants.CA_DOMAIN + "/getPfxCert/" + systemUser.getId() + "?password=" + password;
        return "redirect:" + pfxUrl;
    }

    public String requestDownload(String urlString, String realPath, String ext) {
        String pfxPath = null;
        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //设置超时间为300毫秒
            conn.setConnectTimeout(100);
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            //得到输入流
            InputStream inputStream = conn.getInputStream();
            //获取自己数组
            byte[] getData = readInputStream(inputStream);
            if (getData.length <= 0) {
                return null;
            }

            File realDir = new File(realPath);
            if (!realDir.exists()) realDir.mkdirs();
            pfxPath = realPath  + "/"+ System.currentTimeMillis();
            File pfxFile = new File(pfxPath + ext);
            FileOutputStream fos = new FileOutputStream(pfxFile);
            fos.write(getData);
            if (fos != null) {
                fos.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            logger.info("申请证书失败！");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("系统繁忙！");
            return null;
        }
        return pfxPath + ext;
    }

    public void responseDownload(File file, HttpServletResponse response) {
        if (file.exists()) {
            response.setContentType("application/force-download");
            response.addHeader("Content-Disposition", "attachment;fileName=" + file.getName());
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 初始化证书申请页面
     *
     * @return
     */
    @RequestMapping("/initCerList")
    public ModelAndView initCerList() {
        ModelAndView model = new ModelAndView();
        model.setViewName(cerPage);
        return model;
    }

}
